package com.ticket.sass.admin.util;

import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
public class RedisCacheUtil {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final ValueOperations<String, Object> valueOps;
    private final ListOperations<String, Object> listOps;
    private final SetOperations<String, Object> setOps;
    private final HashOperations<String, String, Object> hashOps;
    
    public RedisCacheUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
        this.valueOps = redisTemplate.opsForValue();
        this.listOps = redisTemplate.opsForList();
        this.setOps = redisTemplate.opsForSet();
        this.hashOps = redisTemplate.opsForHash();
    }
    
    public void setCacheObject(final String key, final Object value) {
        valueOps.set(key, value);
    }
    
    public void setCacheObject(final String key, final Object value, final long timeout, final TimeUnit unit) {
        valueOps.set(key, value, timeout, unit);
    }
    
    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }
    
    public <T> T getCacheObject(final String key) {
        return (T) valueOps.get(key);
    }
    
    public boolean deleteObject(final String key) {
        return redisTemplate.delete(key);
    }
    
    public boolean setKeyExpireTime(final String key, final long timeout, final TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }
    
    
    public long deleteObject(final Collection<String> keys) {
        return redisTemplate.delete(keys);
    }
    
    public long setCacheList(final String key, final List<Object> dataList) {
        return listOps.rightPushAll(key, dataList);
    }
    
    public <T> List<T> getCacheList(final String key) {
        return (List<T>) listOps.range(key, 0, -1);
    }
    
    public long setCacheSet(final String key, final Set<Object> dataSet) {
        return setOps.add(key, dataSet.toArray());
    }
    
    public <T> Set<T> getCacheSet(final String key) {
        return (Set<T>) setOps.members(key);
    }
    
    public void setCacheMap(final String key, final Map<String, Object> dataMap) {
        if (dataMap != null) {
            hashOps.putAll(key, dataMap);
        }
    }
    
    public <T> Map<String, T> getCacheMap(final String key) {
        return (Map<String, T>) hashOps.entries(key);
    }
    
    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
        hashOps.put(key, hKey, value);
    }
    
    public <T> T getCacheMapValue(final String key, final String hKey) {
        return (T) hashOps.get(key, hKey);
    }
    
    public void delCacheMapValue(final String key, final String hKey) {
        hashOps.delete(key, hKey);
    }
    
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<String> hKeys) {
        return (List<T>) hashOps.multiGet(key, hKeys);
    }
    
    public Collection<String> keys(final String pattern) {
        return redisTemplate.keys(pattern);
    }
    
    public boolean lock(String key, String value, long expireTime) {
        Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
        return success != null && success;
    }
    
    public void unlock(String key) {
        redisTemplate.delete(key);
    }
    
}
